﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestDotProductDenseVector.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.DenseVectorTest.DoubleExtensions
{
    #region Usings

    using System;

    using ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="DenseVectorExtensions.DotProduct(DenseVector{double},DenseVector{double})"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions.DenseVectorExtensions")]
    public sealed class TestDotProductDenseVector
    {
        /// <summary>
        ///     Tests the method when multiplier vector has the same length as multiplicand vector.
        /// </summary>
        [Test]
        public void WhenMultiplicandAndMultiplierHaveTheSameLength()
        {
            // Arrange
            var multiplicand = new DenseVector<double>(new double[] { 1, 2, 3 });
            var multiplier = new DenseVector<double>(new double[] { 10, 100, 1000 });

            // Act
            var result = multiplicand.DotProduct(multiplier);

            // Assert
            Assert.That(result, Is.EqualTo(3210).Within(1e-14));
        }

        /// <summary>
        ///     Tests the method when multiplier vector has greater length than multiplicand vector.
        /// </summary>
        [Test]
        public void WhenMultiplierHasGreaterLengthThanMultiplicand()
        {
            // Arrange
            var multiplicand = new DenseVector<double>(new double[] { 1, 2, 3 });
            var multiplier = new DenseVector<double>(new double[] { 10, 100, 1000, 10000 });

            // Act
            var result = multiplicand.DotProduct(multiplier);

            // Assert
            Assert.That(result, Is.EqualTo(3210).Within(1e-14));
        }

        /// <summary>
        ///     Tests the method when multiplier vector has less length than multiplicand vector.
        /// </summary>
        [Test]
        public void WhenMultiplierHasLessLengthThanMultiplicand()
        {
            // Arrange
            var multiplicand = new DenseVector<double>(new double[] { 1, 2, 3 });
            var multiplier = new DenseVector<double>(new double[] { 10, 100 });

            // Act
            var result = multiplicand.DotProduct(multiplier);

            // Assert
            Assert.That(result, Is.EqualTo(210).Within(1e-14));
        }

#if SAFE

        /// <summary>
        ///     Tests the method when multiplicand parameter is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenMultiplicandIsNull()
        {
            // Arrange
            var multiplier = new DenseVector<double>(3);

            // Act and Assert
            Assert.That(
                () => DenseVectorExtensions.DotProduct(null, multiplier),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("multiplicand"));
        }

        /// <summary>
        ///     Tests the method when multiplier parameter is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenMultiplierIsNull()
        {
            // Arrange
            var multiplicand = new DenseVector<double>(3);

            // Act and Assert
            Assert.That(
                () => multiplicand.DotProduct(null),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("multiplier"));
        }

#endif
    }
}